﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace MipsPipelineSimulator
{
    public class RichListView : ListView
    {
        public delegate bool validate(string inputStr);

        private int lastSelectedRow = -1;

        private int subItemSelected = -1;

        private bool[] editableMask = null;

        private validate[] validateDelegates = null;

        private bool enableMenu;

        private TextBox textBox;
        private ContextMenuStrip contextMenuStrip;
        private System.ComponentModel.IContainer components;
        private ToolStripMenuItem deleteToolStripMenuItem;
        private ToolStripMenuItem addToolStripMenuItem;

        public RichListView(int maxColumns,bool enableMenu)
        {
            editableMask = new bool[maxColumns];
            validateDelegates = new validate[maxColumns];
            for (int i = 0; i < maxColumns; i++)
            {
                editableMask[i] = false;
            }
            this.enableMenu = enableMenu;
            InitializeComponent();
        }

        public void SetColumnEditable(int column, validate validateDelegate)
        {
            if (column <= this.Columns.Count && column > 0)
            {
                editableMask[column - 1] = true;
                validateDelegates[column - 1] += validateDelegate;
            }
        }

        private void DisplayTextBox(ListViewItem.ListViewSubItem subItem)
        {
            textBox.Location = new Point(subItem.Bounds.Left, subItem.Bounds.Top);
            if (subItemSelected != 0)
            {
                textBox.Size = new Size(subItem.Bounds.Width, subItem.Bounds.Height);
            }
            else
            {
                textBox.Size = new Size(this.Columns[0].Width, subItem.Bounds.Height);
            }
            textBox.Show();
            textBox.Text = subItem.Text;
            textBox.SelectAll();
            textBox.Focus();
        }

        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.textBox = new System.Windows.Forms.TextBox();
            this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
            this.deleteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.addToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.contextMenuStrip.SuspendLayout();
            this.SuspendLayout();
            // 
            // textBox
            // 
            this.textBox.Location = new System.Drawing.Point(0, 0);
            this.textBox.Name = "textBox";
            this.textBox.Size = new System.Drawing.Size(0, 20);
            this.textBox.TabIndex = 0;
            this.textBox.Visible = false;
            this.textBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBox_KeyPress);
            this.textBox.LostFocus += new System.EventHandler(this.textBox_LostFocus);
            // 
            // contextMenuStrip
            // 
            this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.deleteToolStripMenuItem,
            this.addToolStripMenuItem});
            this.contextMenuStrip.Name = "contextMenuStrip";
            this.contextMenuStrip.Size = new System.Drawing.Size(125, 48);
            this.contextMenuStrip.ItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(this.contextMenuStrip_ItemClicked);
            // 
            // deleteToolStripMenuItem
            // 
            this.deleteToolStripMenuItem.Name = "deleteToolStripMenuItem";
            this.deleteToolStripMenuItem.Size = new System.Drawing.Size(124, 22);
            this.deleteToolStripMenuItem.Text = "删除";
            // 
            // addToolStripMenuItem
            // 
            this.addToolStripMenuItem.Name = "addToolStripMenuItem";
            this.addToolStripMenuItem.Size = new System.Drawing.Size(124, 22);
            this.addToolStripMenuItem.Text = "添加一行";
            // 
            // RichListView
            // 
            this.Controls.Add(this.textBox);
            this.Dock = System.Windows.Forms.DockStyle.Fill;
            this.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.FullRowSelect = true;
            this.GridLines = true;
            this.Size = new System.Drawing.Size(0, 0);
            this.View = System.Windows.Forms.View.Details;
            this.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.RichListView_MouseDoubleClick);
            this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.RichListView_MouseDown);
            this.contextMenuStrip.ResumeLayout(false);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        private void RichListView_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                ListViewItem listViewItem = this.GetItemAt(e.X, e.Y);
                if (listViewItem == null)
                {
                    return;
                }
                lastSelectedRow = this.Items.IndexOf(listViewItem);

                ListViewItem.ListViewSubItem subItem = listViewItem.GetSubItemAt(e.X, e.Y);
                if (subItem == null)
                {
                    return;
                }
                subItemSelected = listViewItem.SubItems.IndexOf(subItem);
                if (editableMask[subItemSelected])
                {
                    DisplayTextBox(subItem);
                }
            }
        }

        private void textBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            //验证
            if (e.KeyChar == 13)
            {
                this.Focus();
                return;
            }

            if (e.KeyChar == 27)
            {
                textBox.Text = this.Items[lastSelectedRow].SubItems[subItemSelected].Text;
                textBox.Hide();
            }
        }

        private void textBox_LostFocus(object sender, EventArgs e)
        {
            //if (FindItemWithText(textBox.Text, false, 0) != null && this.Items[lastSelectedRow].SubItems[subItemSelected].Text != textBox.Text)
            //{
            //    DefinedMsgBox msgBox = new DefinedMsgBox("错误", "该数据已经存在!");
            //    msgBox.ShowDialog(this);
            //    textBox.SelectAll();
            //    return;
            //}
            if (validateDelegates[subItemSelected].Invoke(textBox.Text))
            {
                this.Items[lastSelectedRow].SubItems[subItemSelected].Text = textBox.Text;
                textBox.Hide();
            }
            else
            {
                DefinedMsgBox msgBox = new DefinedMsgBox("错误", "输入格式错误");
                msgBox.ShowDialog(this);
                textBox.SelectAll();
                textBox.Focus();
            }
            return;
        }

        private void contextMenuStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            if (e.ClickedItem == addToolStripMenuItem)
            {
                this.AddItem();
            }
            else if (e.ClickedItem == deleteToolStripMenuItem)
            {
                foreach (ListViewItem li in this.SelectedItems)
                {
                    this.Items.Remove(li);
                }
            }
        }

        private void RichListView_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right && this.enableMenu)
            {
                this.contextMenuStrip.Show(this, e.Location);
            }
        }

        private void AddItem()
        {
            string[] s = new string[2];
            s[0] = "FFFFFFFFFFFFFFFF";
            s[1] = "00";
            ListViewItem l1 = new ListViewItem(s);
            this.Items.Add(l1);
        }
    }
}
